#import kmeans
import math

def matrice_generale(cube):
	#calcul la matrice de distance globale
	#print "m_hydrophobie"
	m_hydrophobie = matrice_distances(cube, "proprietes", "AA_hydrophobes") 
	#print "m_taille"
	m_taille = matrice_distances(cube, "proteine", "longueur")
	#print "m_pI"
	m_pI = matrice_distances(cube, "proprietes", "pI")
	#print "m_chaines"
	m_chaines = matrice_distances(cube, "proteine", "nb_chaines")
	#print  "m_helices"
	m_helices = matrice_distances(cube, "structure", "nb_helices")
	#print "m_feuillets"
	m_feuillets = matrice_distances(cube, "structure", "nb_feuillets")
	#print "m_coudes"
	m_coudes = matrice_distances(cube, "structure", "nb_coudes")
	#print" m_structure"
	m_structure = ponderation([m_helices, m_feuillets, m_coudes], [1, 1, 1])
	#print "m "
	m = ponderation ([m_hydrophobie, m_taille, m_pI, m_chaines, m_structure],[1, 1, 1, 0.5, 0.25])
	return m

def matrice_distances(cube, table, dimension) :
	#calcul de la matrice de distance pour le critere dimension
	matrice=[]
	for i in range (len( cube[table][dimension])):
		matrice.append([])
	for i in range(len(matrice)):
		for j in range (len( cube[table][dimension])):
			matrice[i].append(distance(cube,i,j, table, dimension))
	matrice=centrer_reduire(matrice)
	return [x for x in matrice]
			
			
		
	
	
def distance(cube,a,b,table, dimension):
	#calcul de distance entre a et b pour le critere dimension
	d= math.sqrt(math.pow(float(cube[table][dimension][b])-float(cube[table][dimension][a]),2))
	return d
	
	
def centrer_reduire(matrice):
	#centre et reduit la matrice autour de 0 pour un ecart type de 1
	somme=0.0
	for i in range(len(matrice)):
		for j in range (len(matrice)):
			somme=somme+matrice[i][j]
	moyenne=somme/pow(len(matrice),2)				
	somme_ecarts=0.0
	for i in range(len(matrice)):
		for j in range (len(matrice)):
			somme_ecarts=somme_ecarts+(math.pow(matrice[i][j]-moyenne, 2))
	ecart_type=math.sqrt(somme_ecarts/pow(len(matrice),2))				
	
	for i in range(len(matrice)):
		for j in range (len(matrice)):
			matrice[i][j]=((matrice[i][j]-moyenne)/ecart_type)
	return [x for x in matrice]
	
def ponderation (matrices, poids):
	#calcul une distance ponderee pour plusieurs criteres
	m=[ [0 for x in range(len(matrices[0]))] for x in range(len(matrices[0]) )]
	sommeP=0
	for p in poids :
		sommeP=sommeP+p
		
	for h in range (len(matrices)):
		for i in range (len(matrices[h])):
			for j in range (len(matrices[h][i])):
				m[i][j] = m[i][j] + matrices[h][i][j] * poids[h]/sommeP		
	m=centrer_reduire(m)
	return m
	
